﻿using Company.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Company.Hardware.Base.Helpers
{
    public class TcpService
    {
        private TcpClient tcpClient = new TcpClient();
        private TcpListener tcpListener = null;
        private Config? config = null;
        private CancellationTokenSource cts = new CancellationTokenSource();
        public bool Connected { get; set; } = false;
        public bool IsStarted { get; set; } = false;

        public event Action<string>? OnReceived;

        public async Task<bool> ConnectionTcpServerAsync(Config? config)
        {
            return await Task.Run<bool>(() =>
            {
                this.config = config;
                try
                {
                    if (string.IsNullOrEmpty(config.IpAddress))
                    {
                        Logs.Error($"{this.GetType().FullName}IpAddress不能为空");
                        return false;
                    }
                    //配置的ip地址是否有效
                    bool isValid = false;
                    IPAddress ipAddress = null;
                    if (IPAddress.TryParse(config.IpAddress, out ipAddress))
                    {
                        if (config.IpAddress == "127.0.0.1")
                        {
                            isValid = true;
                        }
                        else
                        {
                            //获取本机IP地址
                            var ips = Dns.GetHostAddresses(Dns.GetHostName()).ToList();
                            foreach (var ip in ips)
                            {
                                if (ip.AddressFamily == AddressFamily.InterNetwork)
                                {
                                    if (ipAddress.ToString() == ip.ToString())
                                    {
                                        isValid = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (isValid)
                        {
                            tcpListener = new TcpListener(ipAddress, config.Port);
                            Connected = true;
                        }
                        else
                        {
                            Logs.Error($"{this.GetType().FullName}初始化失败");
                            return false;
                        }
                    }
                    else
                    {
                        Logs.Error($"{this.GetType().FullName}初始化失败");
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    Logs.Error(ex);
                    return false;
                }
                return true;
            });            
        }

        public async Task<bool> ConnectionTcpClientAsync(Config? config)
        {
            this.config = config;
            try
            {
                if (string.IsNullOrEmpty(config.IpAddress))
                {
                    Logs.Error($"{this.GetType().FullName}IpAddress不能为空");
                    return false;
                }
                await tcpClient.ConnectAsync(config.IpAddress, config.Port);
                if (tcpClient.Connected)
                {
                    Connected= true;
                    return true;
                }
                else
                {
                    Logs.Error($"{this.GetType().FullName}{config.IpAddress}连接失败");

                    return false;
                }
            }
            catch (Exception ex)
            {
                Logs.Error(ex);
                return false;
            }
        }

        private List<TcpClient> tcpClients = new List<TcpClient>();//保持所有来自客户端的请求
        public bool Start()
        {
            if(IsStarted)
            {
                return false;
            }

            if(config.Protocol ==(int)Company.Core.ProtocolType.TcpClient)
            {
                //客户端模式
                Task.Factory.StartNew(Receive, TaskCreationOptions.LongRunning);
            }
            else
            {
                //服务器端模式
                tcpListener.Start();
                Task.Run(() =>
                {
                    while(!cts.IsCancellationRequested)
                    {
                        var tcpClient = tcpListener.AcceptTcpClient();//每接收一个客户端请求生成一个TcpClient实例
                        tcpClients.Add(tcpClient);
                        Task.Factory.StartNew(() =>
                        {
                            while (!cts.IsCancellationRequested)
                            {
                                try
                                {
                                    if (tcpClient == null) break;
                                    if (tcpClient.Available <= 0)
                                    {
                                        Thread.Sleep(1);
                                        continue;
                                    }
                                    byte[] buffer = new byte[tcpClient.Available];//可接收长度
                                    int length = tcpClient.Client.Receive(buffer);//阻塞
                                    byte[] receiveBytes = buffer.Take(length).ToArray();//实际长度
                                    string receiveString = System.Text.Encoding.Default.GetString(receiveBytes);
                                    OnReceived?.Invoke(receiveString);
                                }
                                catch (Exception ex)
                                {
                                   Logs.Error(ex);
                                }
                            }
                        },TaskCreationOptions.LongRunning);
                    }
                });
                IsStarted= true;
            }
            return true;
        }

        //接收来自服务器端的数据
        private void Receive()
        {
            while (!cts.IsCancellationRequested)
            {
                try
                {
                    if(tcpClient == null) break;
                    if (tcpClient.Available <= 0)
                    {
                        Thread.Sleep(1);
                        continue;
                    }
                    byte[] buffer = new byte[tcpClient.Available];//可接收长度
                    int length = tcpClient.Client.Receive(buffer);//阻塞
                    byte[] receiveBytes = buffer.Take(length).ToArray();//实际长度
                    string receiveString = System.Text.Encoding.Default.GetString(receiveBytes);
                    OnReceived?.Invoke(receiveString);
                }
                catch(Exception ex)
                {
                    Logs.Error(ex);
                }
            }
        }

        public bool Close()
        {
            cts.Cancel();
            return true;
        }
    }
}
